<?php
// +----------------------------------------------------------------------
// | Bwsaas
// +----------------------------------------------------------------------
// | Copyright (c) 2015~2020 http://www.buwangyun.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Gitee ( https://gitee.com/buwangyun/bwsaas )
// +----------------------------------------------------------------------
// | Author: buwangyun <hnlg666@163.com>
// +----------------------------------------------------------------------
// | Date: 2020-9-28 10:55:00
// +----------------------------------------------------------------------

namespace app\manage\controller\member;

use app\common\model\member\Wallet;
use app\common\model\MemberMiniapp;
use app\common\model\MemberMiniappAudit;
use app\common\model\MemberMiniappOrder;
use app\common\model\MiniappModule;
use app\manage\model\AuthGroupAccess;
use app\manage\model\Member;
use buwang\base\MemberBaseController;
use buwang\facade\WechatProgram;
use buwang\service\MiniappService;
use buwang\traits\CrudControllerTrait;
use filter\Inspect;
use think\facade\Db;
use think\facade\View;

class Miniapp extends MemberBaseController
{
    use CrudControllerTrait;

    protected $model = null;//模型实例

    protected function initialize()
    {
        parent::initialize();

        $this->model = new \app\common\model\Miniapp();
    }

    /**
     * 查看
     */
    public function index()
    {
        //已启用应用列表
        $list = $this->model->where(['status' => 1])
            ->where("(is_diy = 0 OR (is_diy = 1 AND diy_member_ids LIKE '%,{$this->uid},%'))")
            ->order('id asc')->select();

        View::assign(compact('list'));

        return view();
    }

    /**
     * 应用详情页
     * @param int $id
     * @return \think\response\View
     */
    public function detail($id = 0)
    {
        $detail = $this->model->where(['id' => $id, 'status' => 1])->find();
        if (!$detail) return $this->error_jump('应用不存在');

        //富文本转移
        $detail['content'] = urldecode(urldecode(html_entity_decode($detail['content'])));

        //应用基础功能
        $baseModule = MiniappModule::where(['miniapp_id' => $id, 'type' => 1])->find();
        if (!$baseModule) return $this->error_jump('应用有误,无基础功能');

        //是否已购买基础功能
        $hasBuy = MemberMiniappOrder::where(['member_id' => $this->uid, 'miniapp_id' => $id, 'miniapp_module_id' => $baseModule['id'], 'miniapp_module_type' => 1])->find() ? 1 : 0;

        //NOTE 功能列表 是否已购买
        /*$sql = "SELECT id,miniapp_id,
                    (SELECT title FROM bw_miniapp WHERE id = mm.miniapp_id) as miniapp_title, 
                    name,type,price,valid_days,
                    IFNULL((SELECT id FROM bw_member_miniapp_order WHERE member_id = {$this->uid} AND miniapp_id = {$id}), 0) as hasBuy 
                    FROM bw_miniapp_module mm WHERE miniapp_id = {$id} ORDER BY type asc,id desc";
        $miniappModules = Db::query($sql);*/
        $miniappModules = MiniappModule::where('miniapp_id', $id)->select()->toArray();
        foreach ($miniappModules as &$miniappModule) {
            $miniappModule['has_buy'] = MemberMiniappOrder::where(['member_id' => $this->uid, 'miniapp_id' => $id, 'miniapp_module_id' => $miniappModule['id']])->find() ? 1 : 0;
        }

        View::assign(compact('detail', 'baseModule', 'hasBuy', 'miniappModules'));
        return view();
    }

    public function buy($id = '')
    {
        if (request()->isPost()) {
            $id = $id ?: request()->post("id/d");
            $name = request()->post("name/s");
            $paypwd = request()->post("paypwd/s");

            if ($this->user['parent_id'] != 0) return $this->error('无购买权限');
            //NOTE 验证支付密码
            if (!Member::checkPassword($paypwd, $this->user['safe_password'])) return $this->error('支付密码错误');

            $this->model->startTrans();
            try {
                MiniappService::buy($this->uid, $id, $name);

                $this->model->commit();
            } catch (\Exception $e) {
                $this->model->rollback();
                return $this->error($e->getMessage());
            }
            return $this->success();
        }
    }

    /**
     * 以下部分是微信小程序官方操作
     * ###########################################
     * 设置域名
     */
    public function setDomain()
    {
        self::isMemberAppAuth();
        if ($this->request->isAjax()) {
            $rel = MemberMiniappAudit::where(['member_miniapp_id' => $this->member_miniapp_id, 'member_id' => $this->user->id])->find();
            if (!empty($rel) && $rel->is_commit == 3 && $rel->state == 1) {
                return $this->error('审核中小程序禁止设置业务域名', [], 400020);
            }
            $url['action'] = 'set';
            $url['requestdomain'] = ['https://res.' . $this->request->rootDomain(), 'https://' . $this->request->host()];
            $url['wsrequestdomain'] = ['wss://res.' . $this->request->rootDomain(), 'wss://' . $this->request->host()];
            $url['uploaddomain'] = $url['requestdomain'];
            $url['downloaddomain'] = $url['requestdomain'];
            $mini_program = WechatProgram::isTypes($this->member_miniapp_id);
            if (!$mini_program) {
                return $this->error('小程序还未授权,禁止操作', [], 400021);
            }
            $rel = $mini_program->domain->modify($url);
            if ($rel['errcode'] > 0) {
                $rel['errcode'] == 85015 && $rel['errmsg'] = "该账号不是小程序账号";
                $rel['errcode'] == 85017 && $rel['errmsg'] = "没有新增域名，请确认小程序已经添加了域名或该域名是否没有在第三方平台添加";
                return $this->error('报错信息:' . $rel['errmsg'], [], 400022);
            }
            $mini_program->domain->setWebviewDomain(['https://' . $this->request->rootDomain()]);  //设置业务域名
            $data['is_commit'] = 2;
            $data['member_miniapp_id'] = $this->member_miniapp_id;
            $data['member_id'] = $this->user['id'];
            MemberMiniappAudit::edit(['member_miniapp_id' => $this->member_miniapp_id, 'member_id' => $this->user->id], $data);
            return $this->success('设置域名成功');
        }
    }

    /**
     * 上传代码
     */
    public function upCode()
    {
        self::isMemberAppAuth();
        if ($this->request->isAjax()) {
            $rel = MemberMiniappAudit::where(['member_miniapp_id' => $this->member_miniapp_id, 'member_id' => $this->user->id])->find();
            if (!empty($rel) && $rel->is_commit == 3 && $rel->state == 1) {
                return $this->error('审核中小程序禁止设置业务域名', [], 400020);
            }
            //读取小程序信息
            $app = $this->model->where(['id' => $this->member_miniapp->miniapp_id, 'status' => 1])->find();
            if (empty($app)) {
                return $this->error('小程序不存在或暂停服务', [], 400023);
            }
            //上传参数
            $mini_program = WechatProgram::isTypes($this->member_miniapp_id);
            if (!$mini_program) {
                return $this->error('小程序还未授权,禁止操作', [], 400021);
            }
            $extJson = [
                'extAppid' => $this->member_miniapp->miniapp_appid,
                'ext' => [
                    "name" => $this->member_miniapp->appname,
                    "attr" => [
                        'host' => 'https://' . $this->request->host(),
                        'app_name' => $this->miniapp->dir,
                        'service_id' => $this->member_miniapp->service_id,
                    ],
                ],
                "window" => ['navigationBarTitleText' => $this->member_miniapp->appname]
            ];
            //上传小程序代码
            $upRel = $mini_program->code->commit($this->miniapp->template_id, json_encode($extJson), $this->miniapp->version, $this->miniapp->describe);
            if ($upRel['errcode'] != 0) return $this->error('小程序代码提交上传失败：' . $upRel['errmsg'], [], 400024);
            //更新信息
            $data['is_commit'] = 3;
            $data['member_miniapp_id'] = $this->member_miniapp_id;
            $data['member_id'] = $this->user->id;
            MemberMiniappAudit::edit(['member_miniapp_id' => $this->member_miniapp_id, 'member_id' => $this->user->id], $data);
            return $this->success('代码上传成功，请在审核通过后进行发布代码！');
        }
    }

    /**
     * 提交审核
     * @access public
     */
    public function submitAudit()
    {
        self::isMemberAppAuth();
        if ($this->request->isGet()) {
            $mini_program = WechatProgram::isTypes($this->member_miniapp_id);
            if (!$mini_program) {
                return $this->error_jump('小程序还未授权,禁止操作');
            }
            $cateRes = $mini_program->code->getCategory();  //获取审核时可填写的类目信息,本接口接口可获取已设置的二级类目及用于代码审核的可选三级类目
            if ($cateRes['errcode'] == -1) {
                return $this->error_jump($cateRes['errmsg']);
            }
            $page = $mini_program->code->getPage();  //获取已上传的代码的页面列表,通过本接口可以获取由第三方平台上传小程序代码的页面列表；用于提交审核的审核项 的 address 参数
            if ($page['errcode'] != 0) {
                return $this->error_jump($page['errmsg']);
            }
            $cate = [];
            foreach ($cateRes['category_list'] as $key => $value) {
                $cate[$key]['name'] = empty($value['third_class']) ? $value['first_class'] . '-' . $value['second_class'] : $value['first_class'] . '-' . $value['second_class'] . '-' . $value['third_class'];
                $cate[$key]['id'] = empty($value['third_id']) ? $value['first_id'] . '-' . $value['second_id'] : $value['first_id'] . '-' . $value['second_id'] . '-' . $value['third_id'];
            }
            $view['cate'] = $cate;
            $view['page'] = $page['page_list'];
            $view['id'] = $this->member_miniapp_id;
            View::assign($view);
            return view();
        } else {
            if (request()->isAjax()) {
                $data = [
                    'cate' => $this->request->param('cate[0]/a'),
                    'page' => $this->request->param('page[0]/a'),
                    'name' => $this->request->param('name[0]/a'),
                    'tag' => $this->request->param('tag[0]/a'),
                ];
                //TODO 验证参数
                if ($data['cate']['0'] == "" || $data['page'][0] == "") return $this->error('提交的数据不完善');
                $mini_program = WechatProgram::isTypes($this->member_miniapp_id);
                if (!$mini_program) {
                    return $this->error('小程序还未授权,禁止操作', [], 400021);
                }

                //读取分类
                $getcate = $mini_program->code->getCategory();
                if ($getcate['errcode'] == -1) {
                    return $this->error($getcate['errmsg']);
                }

                //页面一
                $page[0] = ["address" => $data['page'][0], "tag" => $data['tag'][0], "title" => $data['name'][0]];
                $item[0] = array_merge($page[0], $getcate['category_list'][$data['cate']['0']]);

                //提交审核单
                $rel = $mini_program->code->submitAudit($item);
                if ($rel['errcode'] != 0) {
                    return $this->error($rel['errmsg']);
                }
                $code_data['is_commit'] = 3;
                $code_data['state'] = 1;
                $code_data['member_miniapp_id'] = $this->member_miniapp_id;
                $code_data['member_id'] = $this->user->id;
                $code_data['auditid'] = $rel['auditid'];
                MemberMiniappAudit::edit(['member_miniapp_id' => $this->member_miniapp_id, 'member_id' => $this->user->id], $code_data);
                return $this->success('提交审核成功', ['url' => url('/manage/member.setting/' . $this->member_miniapp_id)]);
            } else {
                return $this->error('请求方法不对');
            }
        }

    }

    /**
     * 拉取小程序体验二维码
     */
    public function getQrCode()
    {
        if (request()->isAjax()) {
            $mini_program = WechatProgram::isTypes($this->member_miniapp_id);
            if (!$mini_program) {
                return $this->error('小程序还未授权,禁止操作', [], 400021);
            }
            try {
                $qrcode = $mini_program->code->getQrCode();
            } catch (\Exception $e) {
                return $this->error('小程序还未授权,禁止操作', [], 400021);
            }
            $data['trial_qrcode'] = $this->saveQrCode($qrcode, 'miniapp_' . $this->member_miniapp_id);
            $data['member_miniapp_id'] = $this->member_miniapp_id;
            $data['member_id'] = $this->user->id;
            MemberMiniappAudit::edit(['member_miniapp_id' => $this->member_miniapp_id, 'member_id' => $this->user->id], $data);
            return $this->success('读取体验二维码成功', ['qr_url' => $data['trial_qrcode']]);
        } else {
            return $this->error('读取体验二维码失败');
        }
    }

    /**
     * 查询指定auditid的小程序审核状态
     */
    public function getAuditStatus()
    {
        if (request()->isAjax()) {
            $mini_program = WechatProgram::isTypes($this->member_miniapp_id);
            if (!$mini_program) {
                return $this->error('小程序还未授权,禁止操作', [], 400021);
            }
            $rel = MemberMiniappAudit::where(['member_miniapp_id' => $this->member_miniapp_id, 'member_id' => $this->user->id])->find();
            if (!empty($rel) && $rel->is_commit == 3 && $rel->state == 1) {
                $auditId = $rel['auditid'];
            }
            if (!isset($auditId)) return $this->error('小程序尚未提交审核！');
            try {
                $status = $mini_program->code->getAuditStatus($auditId);
            } catch (\Exception $e) {
                return $this->error($e->getMessage());
            }
            if ($status['errcode'] != 0) {
                return $this->error($status['errmsg']);
            }
            $msgArray = ['审核成功', '审核被拒绝', '审核中', '已撤回', '审核延后'];
            $statusMsg = $msgArray[$status['status']];
            return $this->success('查询结果：' . $statusMsg, ['status' => $status['status'], 'msg' => $statusMsg]);
        } else {
            return $this->error('获取审核状态失败');
        }
    }

    /**
     * 强制撤销审核
     * @access public
     */
    public function resetAudit()
    {
        if (request()->isAjax()) {
            $mini_program = WechatProgram::isTypes($this->member_miniapp_id);
            if (!$mini_program) {
                return $this->error('小程序还未授权,禁止操作', [], 400021);
            }
            $rel = $mini_program->code->withdrawAudit();
            if ($rel['errcode'] == 0) {
                $data['is_commit'] = 2;
                $data['state'] = 0;
                $data['member_miniapp_id'] = $this->member_miniapp_id;
                $data['member_id'] = $this->user->id;
                MemberMiniappAudit::edit(['member_miniapp_id' => $this->member_miniapp_id, 'member_id' => $this->user->id], $data);
                return $this->success('撤回成功');
            } else {
                return $this->error('撤回失败' . $rel['errmsg']);
            }
        } else {
            return $this->error('请求方法错误');
        }
    }

    /**
     * 发布小程序代码 需要先审核成功
     */
    public function publishCode()
    {
        if (request()->isAjax()) {
            $rel = WechatProgram::isTypes($this->member_miniapp_id)->code->release();
            switch ($rel['errcode']) {
                case 0:
                    //修改发布状态
                    MemberMiniappAudit::edit(['member_miniapp_id' => $this->member_miniapp_id, 'member_id' => $this->user->id], ['is_commit' => 4, 'state' => 0, 'member_miniapp_id' => $this->member_miniapp_id, 'member_id' => $this->user->id]);
                    //同步用户已购买应用版本信息
                    MemberMiniapp::where(['id' => $this->member_miniapp_id])->update(['template_id' => $this->member_miniapp->miniapp->template_id, 'version' => $this->member_miniapp->miniapp->version]);
                    return $this->success('发布成功');
                    break;
                case 85019:
                    return $this->error('没有审核版本');
                    break;
                case 85020:
                    return $this->error('审核状态未满足发布');
                    break;
                case -1:
                    return $this->error('系统繁忙');
                    break;
                default:
                    return $this->error($rel['errmsg']);
                    break;
            }
        } else {
            return $this->error('请求方法错误');
        }
    }

    /**
     * 直接把内容保存到服务器
     * @return string
     */
    private function saveQrCode($str, $qrname = 'qrcode')
    {
        $dir = public_path('res/qrcode') . Inspect::filter_escape($qrname);
        is_mkdir($dir);
        $qrname = $dir . '.png';
        file_put_contents($qrname, $str);
        return '/' . str_replace('\\', '/', substr($qrname, strlen(public_path())));
    }
}
